package org.polyforms.repository.strategy.support;

import java.lang.reflect.Method;
import java.util.Set;

import javax.inject.Inject;
import javax.inject.Named;

import org.polyforms.repository.executor.ExecutedBy;
import org.polyforms.repository.executor.Executor;
import org.polyforms.repository.strategy.ExecutorFindingStrategy;

/**
 * Strategy of finding {@link Executor} for method annotated with {@link ExecutedBy}.
 * 
 * @author Kuisong Tong
 * @since 1.0
 */
@Named
public final class AnnotatedExecutorFindingStrategy implements ExecutorFindingStrategy {
    private final Set<Executor> executors;

    /**
     * Create an instance with {@link Executor}s.
     */
    @Inject
    public AnnotatedExecutorFindingStrategy(final Set<Executor> executors) {
        this.executors = executors;
    }

    /**
     * {@inheritDoc}
     */
    public Executor getExecutor(final Method method) {
        final ExecutedBy executedBy = method.getAnnotation(ExecutedBy.class);
        if (executedBy != null) {
            final Class<? extends Executor> executorClass = executedBy.value();
            for (final Executor executor : executors) {
                if (executorClass == executor.getClass()) {
                    return executor;
                }
            }
        }
        return Executor.UNSUPPORT;
    }
}
